/* MODEL.C */

/*
	Copyright (C) 2010 by Lesnikov Andrey <ozkriff@gmail.com>
	This file is part of ozkriff_game_2.

	ozkriff_game_2 is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	ozkriff_game_2 is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with ozkriff_game_2.  If not, see <http://www.gnu.org/licenses/>.

	See the COPYING file for more details.
*/

#include "SDL/SDL.h"
#include "SDL/SDL_opengl.h"
#include "SDL/SDL_image.h"
#include <stdio.h>
//#include <stdlib.h>

#include "defines.h"
#include "model.h"

model mdl[130]; //массив анимаций. пока что только одна модель.
GLuint texture; //ID текстуры персонажа


GLuint
load_texture(char *name)
{
	SDL_Surface *tmp_surface;
	GLenum textureFormat;
	GLuint textureID;
	
	
	
#if(1) //TODO: repair SDL_image loading
	tmp_surface = IMG_Load(name);

	if (tmp_surface->format->BytesPerPixel == 4) {
		if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
			textureFormat = GL_BGRA;
		else
			textureFormat = GL_RGBA;
	} else {
		if (SDL_BYTEORDER == SDL_BIG_ENDIAN)
			textureFormat = GL_BGR;
		else
			textureFormat = GL_RGB;
	}
#else
	tmp_surface = SDL_LoadBMP(name);
#endif
	
	/* Genarate texture */
	glGenTextures(1, &textureID);
	glBindTexture(GL_TEXTURE_2D, textureID);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D, 0, tmp_surface->format->BytesPerPixel,
			tmp_surface->w, tmp_surface->h, 0, textureFormat, //TODO
			//tmp_surface->w, tmp_surface->h, 0, GL_BGR, // => SDL_LoadBMP
			GL_UNSIGNED_BYTE, tmp_surface->pixels);
	             
	SDL_FreeSurface(tmp_surface);
	
	return(textureID);
}



model
read_obj_file(char* filename)
{
	model mdl;
	char buffer[100];
	FILE *obj_file = NULL;
	
	int v_count=0, vn_count=0, vt_count=0, f_count=0;
	
	
	obj_file = fopen(filename, "r");
	if (obj_file == NULL)
	{
		printf("can't find file: %s", filename);
		exit(6);
	}
#if(0)
	
	int v=0, vn=0, vt=0, f=0;
	while (fgets(buffer, 100, obj_file))
	{
		if     (buffer[0]=='v' && buffer[1]==' ')
			v++;
		else if(buffer[0]=='v' && buffer[1]=='n')
			vn++;
		else if(buffer[0]=='v' && buffer[1]=='t')
			vt++;
		else if(buffer[0]=='f' && buffer[1]==' ') 
			f++;
	}
	//_v_count=1000, _vn_count=1000, _vt_count=1000, _f_count=1000;
	
	mdl.vertexes 	= malloc((2+v) *sizeof(vector));
	mdl.normals 	= malloc((2+vn)*sizeof(vector));
	mdl.text_coords = malloc((2+vt)*sizeof(texture_coords));
	mdl.faces 	= malloc((2+f) *sizeof(indexes));

	
	rewind(obj_file);
#endif
	
	while (fgets(buffer, 100, obj_file))
	{
		/* puts(buffer); */
		/* vertex coords */
		if (buffer[0] == 'v' && buffer [1] == ' ') {
			v_count++;
			sscanf(buffer, "v %f %f %f",
			       &mdl.vertexes[v_count].x,
			       &mdl.vertexes[v_count].y,
			       &mdl.vertexes[v_count].z);
			       
#define resize_coefficient (0.10) //remove later
#if(1)
			mdl.vertexes[v_count].x *= resize_coefficient;
			mdl.vertexes[v_count].y *= resize_coefficient;
			mdl.vertexes[v_count].z *= resize_coefficient;
#endif
		}
		
		/* vertex normals */
		else if (buffer[0] == 'v' && buffer[1] == 'n') {
			vn_count++;
			sscanf(buffer, "vn %f %f %f",
			       &mdl.normals[v_count].x,
			       &mdl.normals[v_count].y,
			       &mdl.normals[v_count].z);
		}
		
		/* texture coords */
		else if (buffer[0] == 'v' && buffer[1] == 't') {
			vt_count++;
			sscanf(buffer, "vt %f %f",
			       &mdl.text_coords[vt_count].v,
			       &mdl.text_coords[vt_count].u);
		}
		
		/* faces */
		else if (buffer[0] == 'f' && buffer [1] == ' ') {
			int slash_count = 0;
			f_count++;
			int i;
			for (i = 2; buffer[i] != ' '; i++)
				if (buffer[i] == '/')
					slash_count++;
			/* printf("%i\n", slash_count); */
			
			if (slash_count == 1)
				sscanf(buffer, "f %i/%i %i/%i %i/%i",
				       &mdl.faces[f_count].v1,  &mdl.faces[f_count].vt1,
				       &mdl.faces[f_count].v2,  &mdl.faces[f_count].vt2,
				       &mdl.faces[f_count].v3,  &mdl.faces[f_count].vt3
				      );
			else if (slash_count == 2)
				sscanf(buffer, "f %i/%i/%i %i/%i/%i %i/%i/%i",
				       &mdl.faces[f_count].v1,  &mdl.faces[f_count].vt1, &mdl.faces[f_count].vn1,
				       &mdl.faces[f_count].v2,  &mdl.faces[f_count].vt2, &mdl.faces[f_count].vn2,
				       &mdl.faces[f_count].v3,  &mdl.faces[f_count].vt3, &mdl.faces[f_count].vn3);
			else {
				puts("ERRRRORRRR!!!");
				exit(0);
			}
			
		}
	}
	
	fclose(obj_file);
	
#if(0) // AFTERSCAN_PRINT
	printf("vertex count: %i\n", v_count);
	printf("texture coords count: %i\n", vt_count);
	printf("faces count: %i\n", f_count);
#endif
	
	mdl.f_count = f_count; //remember for each model. later we'll use it for rendering
	
	return(mdl);
}



void
draw_model(/*int texnum, */model mdl)
{
	int ii = 0;
	
	//glBindTexture(GL_TEXTURE_2D, texture[texnum]);    /* Select Texture */
	glBindTexture(GL_TEXTURE_2D, texture);
	//glBindTexture(GL_TEXTURE_2D, sky_texture[3]);
	
	glBegin(GL_TRIANGLES);
	{
		for (ii = 0; ii <= mdl.f_count; ii++)
		{
			/* TODO: remake whole structure. */
			glTexCoord2f(mdl.text_coords[ mdl.faces[ii].vt1 ].u,
				     mdl.text_coords[ mdl.faces[ii].vt1 ].v);
			glVertex3f(mdl.vertexes   [ mdl.faces[ii].v1  ].x,
				   mdl.vertexes   [ mdl.faces[ii].v1  ].y,
				   mdl.vertexes   [ mdl.faces[ii].v1  ].z);
			//glNormal3f(mdl.normals   [ mdl.faces[ii].v1  ].x,
			//	   mdl.normals   [ mdl.faces[ii].v1  ].y,
			//	   mdl.normals   [ mdl.faces[ii].v1  ].z);
			
			glTexCoord2f(mdl.text_coords[ mdl.faces[ii].vt2 ].u,
				     mdl.text_coords[ mdl.faces[ii].vt2 ].v);
			glVertex3f(mdl.vertexes   [ mdl.faces[ii].v2  ].x,
				   mdl.vertexes   [ mdl.faces[ii].v2  ].y,
				   mdl.vertexes   [ mdl.faces[ii].v2  ].z);
			//glNormal3f(mdl.normals   [ mdl.faces[ii].v1  ].x,
			//	   mdl.normals   [ mdl.faces[ii].v1  ].y,
			//	   mdl.normals   [ mdl.faces[ii].v1  ].z);
			
			glTexCoord2f(mdl.text_coords[ mdl.faces[ii].vt3 ].u,
				     mdl.text_coords[ mdl.faces[ii].vt3 ].v);
			glVertex3f(mdl.vertexes   [ mdl.faces[ii].v3  ].x,
				   mdl.vertexes   [ mdl.faces[ii].v3  ].y,
				   mdl.vertexes   [ mdl.faces[ii].v3  ].z);
			//glNormal3f(mdl.normals   [ mdl.faces[ii].v1  ].x,
			//	   mdl.normals   [ mdl.faces[ii].v1  ].y,
			//	   mdl.normals   [ mdl.faces[ii].v1  ].z);
		}
	}
	glEnd();
}


